package com.gilight.base.base;

import com.alibaba.fastjson.JSON;
import com.gilight.base.base.exception.AppServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.rmi.UnexpectedException;

/**
 * Created by zhaowuz on 2018/8/21.
 * 统一异常处理
 */
@ResponseBody
@ControllerAdvice(basePackages = "com.gilight")
public class GlobalExceptionHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(Throwable.class)
    public ResultEntity handlerException(Throwable throwable, HttpServletRequest request) {
        LOGGER.error("请求地址:{} 请求参数:{}", request.getRequestURI(), JSON.toJSONString(request.getParameterMap()));
        LOGGER.error(">>>>>>>>>>>>>>>>>>>>未知异常<<<<<<<<<<<<<<<<<<<<<<<<<<<", throwable);
        return new ResultEntity(RepStatusCode.UNKNOWN_ERROR);
    }

    /**
     * 请求参数绑定异常
     * @param serviceui
     * @param request
     * @return
     */
    @ExceptionHandler(ServletRequestBindingException.class)
    public ResultEntity handlerRequestBinding(ServletRequestBindingException serviceui, HttpServletRequest request) {
        LOGGER.error("请求地址:{} 请求参数:{}", request.getRequestURI(), JSON.toJSONString(request.getParameterMap()));
        LOGGER.error(">>>>>>>>>>>>>>>>>>>>参数异常<<<<<<<<<<<<<<<<<<<<<<<<<<<", serviceui);
        return new ResultEntity<>(RepStatusCode.ILLEGAL_PARAMETER_ERROR, serviceui.getLocalizedMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultEntity handleNotValid(MethodArgumentNotValidException exception, HttpServletRequest request) {
        LOGGER.error("请求地址:{} 请求参数:{}", request.getRequestURI(), JSON.toJSONString(request.getParameterMap()));
        LOGGER.error(">>>>>>>>>>>>>>>>>>>>参数异常<<<<<<<<<<<<<<<<<<<<<<<<<<<", exception);
        BindingResult result = exception.getBindingResult();
        if(result.hasErrors()){
            return new ResultEntity<>(RepStatusCode.ILLEGAL_PARAMETER_ERROR,result.getFieldError().getDefaultMessage());
        }
        return new ResultEntity<>(RepStatusCode.ILLEGAL_PARAMETER_ERROR);
    }

    @ExceptionHandler(BindException.class)
    public ResultEntity handleNotValid(BindException exception, HttpServletRequest request) {
        LOGGER.error("请求地址:{} 请求参数:{}", request.getRequestURI(), JSON.toJSONString(request.getParameterMap()));
        LOGGER.error(">>>>>>>>>>>>>>>>>>>>参数异常<<<<<<<<<<<<<<<<<<<<<<<<<<<", exception);
        BindingResult result = exception.getBindingResult();
        if(result.hasErrors()){
            return new ResultEntity<>(RepStatusCode.ILLEGAL_PARAMETER_ERROR,result.getFieldError().getDefaultMessage());
        }
        return new ResultEntity<>(RepStatusCode.ILLEGAL_PARAMETER_ERROR);
    }

    /**
     * 捕获主动抛出的业务异常信息
     * @param baseException
     * @param request
     * @return
     */
    @ExceptionHandler(BaseException.class)
    public ResultEntity hndlerBusinessException(BaseException baseException, HttpServletRequest request) {
        LOGGER.error("请求地址:{} 请求参数:{}", request.getRequestURI(), JSON.toJSONString(request.getParameterMap()));
        LOGGER.error(">>>>>>>>>>>>>>>>>>>>参数异常<<<<<<<<<<<<<<<<<<<<<<<<<<<", baseException);
        return new ResultEntity<>(RepStatusCode.BUSINESS_ERROR, baseException.getMessage());
    }

    //TODO 权限
    @ExceptionHandler(AppServiceException.class)
    public AppServiceException handlerAppException(AppServiceException exception, HttpServletRequest request) {
        LOGGER.error("请求地址:{} 请求参数:{}", request.getRequestURI(), JSON.toJSONString(request.getParameterMap()));
        LOGGER.error(">>>>>>>>>>>>>>>>>>>>App请求异常<<<<<<<<<<<<<<<<<<<<<<<<<<<", exception);
        return exception;
    }
    @ExceptionHandler(UnexpectedException.class)
    public ResultEntity handlerRoleBackException(ServletRequestBindingException serviceui, HttpServletRequest request) {
        LOGGER.error("请求地址:{} 请求参数:{}", request.getRequestURI(), JSON.toJSONString(request.getParameterMap()));
        LOGGER.error(">>>>>>>>>>>>>>>>>>>>参数异常<<<<<<<<<<<<<<<<<<<<<<<<<<<", serviceui);
        return new ResultEntity<>(RepStatusCode.ILLEGAL_PARAMETER_ERROR, serviceui.getLocalizedMessage());
    }
}
